<!--
 * @Descripttion: 
 * @Author: yuxi
 * @Date: 2022-09-16 08:42:55
 * @LastEditors: yuxi
 * @LastEditTime: 2023-01-17 08:53:21
-->
<template>
  <div class="vector-layer">
    <slot></slot>
    <MiningStyleControl
      v-if="modifyStyle"
      :defaultStyle="modifyStyle"
      @submit="endModifyStyle"
      @cancel="modifyStyle = null"
    ></MiningStyleControl>
  </div>
</template>
<script>
import commonMixin from '../mixins/base.js'
import { Vector as VectorSource, Cluster as ClusterSource } from 'ol/source'
import { Vector as VectorLayer } from 'ol/layer'
import { ModifyStyle, DefaultStyle } from '../Config'
import { MiningStyle } from '../Style/index.js'
import MiningStyleControl from '../Control/StyleControl'
import { LineString, Point, Polygon } from 'ol/geom'

import { Circle as CircleStyle, Fill, Stroke, Style, Text } from 'ol/style.js'

const activeModifyStyle = new MiningStyle()
activeModifyStyle.fromJSON(ModifyStyle)

const defaultStyle = new MiningStyle()
defaultStyle.fromJSON(DefaultStyle)

const defaultPointStyle = new MiningStyle()
defaultPointStyle.fromJSON({
  image: DefaultStyle.image,
})

const defaultLineStyle = new MiningStyle()
defaultLineStyle.fromJSON({
  stroke: DefaultStyle.stroke,
})

const defaultPolygonStyle = new MiningStyle()
defaultPolygonStyle.fromJSON({
  stroke: DefaultStyle.stroke,
  fill: DefaultStyle.fill,
})

const styleCache = {}

export default {
  name: 'MiningVectorLayer',
  mixins: [commonMixin('layer')],
  // render () { return '' },
  components: {
    MiningStyleControl,
  },
  props: {
    // 要素
    features: {
      type: Array,
      default () {
        return []
      },
    },
    // 全局要素样式
    featureStyle: {
      type: Object,
      default () {
        return null
      },
    },
    isCluster: {
      type: Boolean,
      default () {
        return false
      },
    },
  },
  data () {
    return {
      source: null,
      layer: null,
      needModify: false,
      activeFeature: null, //激活要素
      editing: false, // 是否激活编辑
      modifyStyle: null,
      modifyFeature: null,
      activeChildren: null
    }
  },
  computed: {
    // 激活编辑的要素实例
   
    customContextMenus () {
      console.log('customContextMenus v2', this.activeChildren, this.editing)
      return this.activeChildren
        ? this.activeChildren.getModifyContextMenus(this.editing)
        : []
    },
  },
  watch: {
    properties () {
      this.setProperties()
    },
    needModify: {
      immediate: true,
      handler () {
        this.needModify ? this.registerModify() : this.disposeModify()
      },
    },
    customContextMenus () {
      this.setMapContextMenus()
    },
    editing () {
      console.log('editing', this.editing)
    },
    activeChildren () {
      console.log('activeChildren is ' + !!this.activeChildren, this.activeChildren)
    },
    // activeFeature () {
    //   this.setActiveChildren()
    // }
  },
  beforeDestroy () {
    this.dispose()
  },
  methods: {
    setActiveChildren(feature) {
      console.log('[VectorLayer] setActiveChildren', this.editing)
      if (feature) {
        let id = feature.feature.getId()
        this.activeChildren = this.getChildrenById(id)
      } else {
        this.activeChildren = null
      }
    },
    styleFun (feature) {
      if (this.isCluster) {
        const size = feature.get('features').length
        if (size === 1) {
          return this.featureStyle ? this.featureStyle : undefined
        } else {
          let style = styleCache[size]
          if (!style) {
            style = new Style({
              image: new CircleStyle({
                radius: 10,
                stroke: new Stroke({
                  color: '#fff',
                }),
                fill: new Fill({
                  color: '#3399CC',
                }),
              }),
              text: new Text({
                text: size.toString(),
                fill: new Fill({
                  color: '#fff',
                }),
              }),
            })
            styleCache[size] = style
          }
          return style
        }
      } else {
        return this.featureStyle ? this.featureStyle : undefined
      }

    },
    dispose () {
      console.log('11 layer dispose')
      this.map.removeLayer(this.layer)
    },
    load () {
      console.log('11 layer load', this.layer)
      console.log(`[${this.$options.name}]获取到${this.features.length}个要素`)
      const { map } = this

      if (this.isCluster) {
        this.source = new ClusterSource({
          distance: 10,
          minDistance: 10,
          source: new VectorSource({
            features: this.features,
          }),
        })
      } else {
        this.source = new VectorSource({
          features: this.features,
        })
      }

      console.log('featureStyle', this.featureStyle)

      this.layer = new VectorLayer({
        source: this.source,
        // style: this.featureStyle ? this.featureStyle : undefined,
        properties: {
          layerName: this.layerName,
          layerId: this.layerId,
          addLayerControl: this.addLayerControl,
          editAble: this.editAble,
          properties: this.properties,
        },
        style: this.styleFun,
      })
      map.addLayer(this.layer)
      console.log(`[${this.$options.name}]矢量图层初始化完毕，并加载地图`)
      this.layer.getSource().on('addfeature', this.handleAddFeature)
      this.layer.getSource().on('removefeature', this.handleRemoveFeature)
    },
    setProperties () {
      this.layer && this.layer.set('properties', this.properties)
    },
    getChildrenById (id) {
      return this.$children.find((c) => {
        return c.id && c.id === id
      })
    },
    handleAddFeature (evt) {
      console.log('handleAddFeature', evt)
      let { feature } = evt
      if (feature) {
        // let properties = feature.get('properties')
        let id = feature.getId()
        let children = this.getChildrenById(id)
        console.log('id', children)
        if (children && children.needModify) {
          this.needModify = true
        }
      }
    },
    handleRemoveFeature (evt) {
      console.log('handleRemoveFeature', evt)
      // 未实现 取消编辑
      // let { feature } = evt
      // if(feature) {
      //   let properties = feature.get('properties')
      //   let id = feature.getId()
      //   let children = this.getChildrenById(id)
      //   if(children && children.needModify) {
      //     this.needModify = true
      //   }
      // }
    },
    registerModify () {
      console.log('[VectorLayer] registerModify')
      this.map && this.map.on('pointermove', this.mouseMove)
    },
    disposeModify () {
      this.map && this.map.off('pointermove', this.mouseMove)
    },
    mouseMove (evt) {
      // 监控鼠标位置变化
      console.log('[VectorLayer] mouseMove editing', this.editing, this.activeFeature)
      if (this.editing) {
        return
      }
      let active = this.map.forEachFeatureAtPixel(
        evt.pixel,
        function (feature, layer) {
          return {
            feature: feature,
            layer: layer,
          }
        },
        {
          hitTolerance: 10,
        }
      )
      if (active) {
        this.activeFeature = active
        // this.activeFeature.feature.setStyle(activeModifyStyle)
      } else if (this.activeFeature) {
        // this.activeFeature.feature.setStyle(this.style)
        // this.resetFeatureStyle(this.activeFeature.feature)
        this.activeFeature = null
      }
      this.setActiveChildren(this.activeFeature)

    },
    // 重置要素样式
    resetFeatureStyle (feature) {
      let properties = feature.get('properties')
      let style = properties.style
      if (style) {
        let localStyle = new MiningStyle()
        localStyle.fromJSON(JSON.parse(style))
        feature.setStyle(localStyle)
      } else {
        feature.setStyle(defaultStyle)
      }
    },
    // 设置地图右键菜单
    setMapContextMenus () {
      // console.log('setMapContextMenus', this.customContextMenus)
      // console.log(this.$parent)
      this.$parent.contextMenus = this.customContextMenus
    },
    // 编辑完成
    endModify () {
      // this.activeFeature.feature.setStyle(this.style)
      console.log('endModify')
      this.editing = false
      this.activeFeature = null
      this.activeChildren = null
    },
    startModify (feature) {
      this.editing = true
      this.setActiveChildren({feature})
      console.log('startModify', this.editing)
    },
    startModifyStyle (feature) {
      this.modifyFeature = feature
      let properties = feature.get('properties')
      console.log('startModifyStyle', properties)
      console.log(feature.getGeometry() instanceof Point)
      let styleObj = properties.style
      let style = null
      if (styleObj) {
        style = new MiningStyle()
        style.fromJSON(JSON.parse(styleObj))
      } else {
        if (feature.getGeometry() instanceof Point) {
          console.log('defaultPointStyle', defaultPointStyle)
          style = defaultPointStyle.clone()
        } else if (feature.getGeometry() instanceof LineString) {
          style = defaultLineStyle.clone()
        } else if (feature.getGeometry() instanceof Polygon) {
          style = defaultPolygonStyle.clone()
        } else {
          style = defaultStyle.clone()
        }
      }
      this.modifyStyle = style
      console.log('startModifyStyle is ', this.modifyStyle)
    },
    endModifyStyle (style) {
      this.modifyStyle = null

      let id = this.modifyFeature.getId()
      let modifyChildren = this.getChildrenById(id)
      console.log(modifyChildren)
      modifyChildren && modifyChildren.endStyleEdit(style)
      this.modifyFeature = null
    },
  },
}
</script>

<style lang="less" scoped>
.vector-layer {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  overflow: visible;
}
</style>
